home *** CD-ROM | disk | FTP | other *** search
- */beginfile PROCESSOR_asm
- ; --------------------------------------------------------------
- ; PROCESSOR_asm - QDOS processor specific routines
- ; - last modified 04/08/95
- ; QDOS-Amiga sources by Rainer Kowallik
- ; ...latest changes by Mark J Swift
- ; ...68040/68060 changes by SNG, 16/8/94
- ; --------------------------------------------------------------
- ;*/beginoverlay
- ; -------------------------------------------------------------
- ; check attn flags for 68000/008 processor. Returns Z if so
-
- CHK6800X:
- movem.l d1/a6,-(a7)
-
- bsr GET_ATTN
- btst #0,d1
-
- movem.l (a7)+,d1/a6
- rts
-
- ; -------------------------------------------------------------
- ; set attn flags for processor.
-
- SET_ATTN:
- movem.l d0/a6,-(a7)
-
- move.l a7,d1 ; Calculate start of
- andi.w #-$8000,d1 ; system variables
- move.l d1,a6
-
- bsr ATTN_FLGS
- move.w d0,d1
- move.w d1,SV_IDENT+2(a6) ; set attn flags
-
- movem.l (a7)+,d0/a6
- rts
-
- ; -------------------------------------------------------------
- ; get attn flags for processor.
-
- GET_ATTN:
- movem.l d0/a6,-(a7)
-
- move.l a7,d1 ; Calculate start of
- andi.w #-$8000,d1 ; system variables
- move.l d1,a6
- move.w SV_IDENT+2(a6),d1 ; get attn flags
-
- movem.l (a7)+,d0/a6
- rts
-
- ; -------------------------------------------------------------
- ; create attention flags (check processor type)
-
- ; bit 0 - at least 68010
- ; bit 1 - at least 68020
- ; bit 2 - at least 68030
- ; bit 3 - at least 68040
- ; bit 4 - at least 68881 (possibly 68882)
- ; bit 5 - 68882 present (or emulation)
- ; bit 6 - 68040 or 68060 on-chip FPU enabled
- ; bit 7 - at least 68060
- ;
- ; Note: If the MC68060 FPU has been turned off in software since
- ; the last reset (which enables it) bit 6 is zero, as if the FPU
- ; was not present and we were using an EC or LC processor.
- ;
- ATTN_FLGS:
- movem.l d1/a0-a3,-(a7)
-
- dc.w $2078,$0010 ; move.l $10.w,a0
- dc.w $2478,$002C ; move.l $2C.w,a2
-
- lea LF80C18(pc),a1
- dc.w $21C9,$0010 ; move.l a1,$10.w
- ; (ILLEGAL INSTRUCTION vector)
- dc.w $21C9,$002C ; move.l a1,$2C.w
- ; (F-LINE EMULATION vector)
-
- move.l a7,a1
-
- moveq #$0,d0 ; initialise attn flags
- move.b #0,161(a6) ; ditto for QDOS
-
- dc.w $4E7B,$0801 ; movec d0,vbr
- bset #$0,d0 ; vbr present - 68010 at least
-
- ; Clear Data cache
- ; | Freeze Data cache
- ; | |Enable Data cache (off)
- ; | || Clear Instruction cache
- ; | || | Enable Instruction cache
- ; | || | |
- move.l #%0000101000001001,d1
-
- dc.w $4E7B,$1002 ; movec d1,cacr
- dc.w $4E7A,$1002 ; movec cacr,d1
- bset #$1,d0 ; cacr present - 68020 at least
- move.b #$20,161(a6) ; store for QDOS
-
- btst #$9,d1
- beq.s LF80BB4 ; no data cache - not a 68030
-
- bset #$2,d0 ; definitely a 68030
- move.b #$30,161(a6) ; store for QDOS
-
- LF80BB4:
- btst #$0,d1
- bne.s LF80BDC ; cacr present and (EI) bit
- ; operative - not a 68040
-
- or.w #$C,d0 ; 68040 at least!
- move.b #$40,161(a6) ; store for QDOS
-
- dc.w $F4D8 ; CINVA ic/dc - inavalidate caches
- ;
- ; This code set up the TTR/ACU registers to stop data cacheing of memory
- ; in the first 16 Mb. This is not needed under Amiga Qdos as the cache is
- ; explicitly cleared when necessary after DMA,
- ;
- ; SNG move.l #$C040,d1 ; Serialize 0-16 Mb
- ; moved: dc.w $4E7B,$1006 ; movec d1,(006)
-
- moveq #0,d1 ; MMU off
- dc.w $4E7B,$1003 ; movec d1,TCR
-
- move.l #$FFC000,d1 ; ACU/TTU off
-
- dc.w $4E7B,$1007 ; movec d1,(007)
- dc.w $4E7B,$1004 ; movec d1,(004)
- dc.w $4E7B,$1005 ; movec d1,(005)
- dc.w $4E7B,$1006 ; movec d1,(006) - moved by SNG
-
- move.l #$80008000,d1 ; Both caches on, for 040+
- bra.s SetCACR
-
- LF80BDC:
- ; Enable Instruction cache >=040 (1=ON)
- ; | Write Allocation (1=ON)
- ; | | Clear Data cache
- ; | | | Enable Data cache (1=ON)
- ; | | | | Clear Instruction cache
- ; | | | | | Enable Instruction cache
- ; | | | | | |
- move.l #%1010100100001001,d1
-
- SetCACR dc.w $4E7B,$1002 ; movec d1,cacr
-
- btst #$3,d0
- beq.s LF80BF6 ; skip if not a 68040 or later
- ;
- ; 68060 initialisation added here
- ;
- ; Note this tests the new PCR register to find out if we're on
- ; an 060. If this fails, the routine returns after checking for
- ; a 68040 FPU. Otherwise it turns on the 060 accelerators and
- ; reports the presence of an enabled FPU, if it finds one.
- ;
- lea NoPCR(pc),a3 ; Continuation if PCR absent
- dc.w $21CB,$0010 ; move.l a3,$10.w
- ; (ILLEGAL INSTRUCTION vector)
-
- dc.w $4E7A,$1808 ; 68060 PCR to D1 or illegal
- swap d1
- cmp.w #$0431,d1
- beq.s No60FPU ; No FPU!
- ; cmp.w #$0430,d1 ; The only other possibility
- ; bne.s Unknown ; at the time of writing...
- btst #17,d1 ; Test swapped DFP flag bit
- bne.s No60FPU ; If FPU is disabled, leave off
-
- bset #6,d0 ; Note 68060 FPU is available
-
- No60FPU bset #7,d0 ; Set 060 bit in ATTN flags
- move.b #$60,161(a6) ; Tell Qdos we're on an 060
- swap d1
- bset #0,d1 ; Ensure SOEP is on
- dc.w $4E7B,$1808 ; Store updated PCR
- ;
- ; Enable store buffer, code, data and (cleared) branch cache
- ;
- move.l #$A0C08000,d1 ; EDC+ESB+EBC+CABC+EIC
- dc.w $4E7B,$1002 ; movec d1,cacr
- bra.s LF80C18
- ;
- ; The old code to check for the 040 FPU always failed because the
- ; 68040 does not support cpSAVE and cpRESTORE! Substitute FNOP
- ;
- ; dc.w $F327 ; cpSAVE
- ; dc.w $F35F ; cpRESTORE
-
- TryFPU dc.w $F280,0 ; FNOP sifts out ECs and LCs
-
- bset #$6,d0 ; 68040 FPU present
- bra.s LF80C18
-
- NoPCR movea.l a1,a7 ; Tidy stacked exception frame
- bra.s TryFPU
- ;
- ; Test for an off-CPU co-processor
- ;
- LF80BF6:
- moveq #$0,d1
-
- dc.w $F201,$9000 ; FMOVE D1 to FPU
- dc.w $F201,$B000 ; FMOVE FPU to D1
-
- tst.l d1 ; A most unlikely case
- bne.s LF80C18 ; Something strange has happened
-
- bset #$4,d0 ; 68881 at least
-
- dc.w $F327 ; cpSAVE -(A7)
-
- cmpi.b #$18,$1(a7) ; Check for 68882 frame
- beq.s LF80C16
-
- bset #$5,d0 ; 68882 at least
-
- LF80C16:
- dc.w $F35F ; cpRESTORE (A7)+
-
- LF80C18:
- move.l a1,a7 ; clean-up stack
-
- dc.w $21C8,$0010 ; move.l a0,$10.w
- dc.w $21CA,$002C ; move.l a2,$2C.w
-
- movem.l (a7)+,d1/a0-a3
- rts
-
- ; -------------------------------------------------------------
- ; clear data and instruction caches
-
- CLRALL:
- movem.l d0-d1/d4,-(a7)
-
- move.l #$808,d1
- bra.s L0000C3E
-
- ; -------------------------------------------------------------
- ; clear data caches
-
- CLRDATA:
- movem.l d0-d1/d4,-(a7)
-
- moveq #$8,d1
- rol.l #8,d1
-
- ; -------------------------------------------------------------
- ; clear cache(s). d1=$800 - clear data cache
- ; d1=$808 - clear data and instruction caches
-
- ; and on 68040/060 - update memory from caches
-
- L0000C3E:
- move.w sr,-(a7)
- ori.w #$0700,sr ; interrupts off
-
- exg d1,d4
- bsr GET_ATTN
- exg d1,d4
-
- btst #$1,d4 ; branch if '020 or more
- bne.s L0000C48
-
- ifd ShoCach
- move.l d7,-(a7)
- move.w #$8000,d7
- WAITBLU:
- move.w #$000F,$DFF180
- move.w #0,$DFF180
- dbra d7,WAITBLU
- move.l (a7)+,d7
- endif
-
- bra.s CLRCACHEX ; ...otherwise exit
-
- L0000C48:
- btst #$3,d4
- bne.s L0000C68 ; '040 ?
- ;
- ; No explicit test for the 060 is needed as long as the 040
- ; bit remains set by tests on a 68060.
- ;
- ; btst #$7,d4 ; Check for '060
- ; bne.s L0000C68
-
- and.l #$808,d1
- ori #$700,sr
- dc.w $4E7A,$0002 ; movec cacr,d0
- or.l d1,d0
- dc.w $4E7B,$0002 ; movec d0,cacr
-
- ifd ShoCach
- move.l d7,-(a7)
- move.w #$8000,d7
- WAITRED:
- move.w #$0F00,$DFF180
- move.w #0,$DFF180
- dbra d7,WAITRED
- move.l (a7)+,d7
- endif
-
- bra.s CLRCACHEX
-
- L0000C68:
- btst #$3,d1
- bne.s L0000C74
-
- dc.w $F478 ; CPUSHA dc ('040 only)
- ; update memory from cache
- bra.s L0000C76
-
- L0000C74:
- dc.w $F4F8 ; CPUSHA ic/dc ('040 only)
- ; update memory from caches
- L0000C76:
- ifd ShoCach
- move.l d7,-(a7)
- move.w #$8000,d7
- WAITGRN:
- move.w #$00F0,$DFF180
- move.w #0,$DFF180
- dbra d7,WAITGRN
- move.l (a7)+,d7
- endif
-
- CLRCACHEX:
- move.w (a7)+,sr
- movem.l (a7)+,d0-d1/d4
- tst.l d0
-
- rts
-
- ; -------------------------------------------------------------
- ; set bits in cacr d0=bits to set d1=bits to clear/alter
- ; This assumes 030 control register bits and tries to rework
- ; them for the 040. It fails, and won't suit 060 either. Luckily
- ; Mark says it is not used or needed in current Qdos versions.
-
- ifne 0 ; Ignore this code block
-
- L0000C8E:
- movem.l d2-d4,-(a7)
-
- moveq #$0,d3
-
- exg d1,d4
- bsr GET_ATTN
- exg d1,d4
-
- btst #$1,d4 ; exit if not at least '020
- beq.s L0000CAE
-
- and.l d1,d0
- or.w #$808,d0 ; signal always clear caches
- not.l d1
-
- L0000CB6:
- ori #$700,sr ; DODGY? Not restored later
- dc.w $4E7A,$2002 ; movec cacr,d2
- btst #$3,d4
- beq.s L0000CD0 ; skip if not '040
- ;
- ; Attempts to convert 040 CACR to 030 form;
- ;
-
- move.l d2,d3
- andi.l #$7FFF0000,d3 ; keep '060 bits...
-
- ; mimick ED & EI
-
- swap d2 ; 8000 8000
- ror.w #8,d2 ; 8000 0080
- rol.l #1,d2 ; 0000 0101
- andi.w #$0101,d2 ; ...only relevant bits
-
- move.w d2,d3 ; mimick DBE & IBE
- rol.w #4,d3 ; 0000 1010
- or.l d3,d2 ; 0000 1111
-
- L0000CD0:
- move.l d2,d3 ; cache register to d3
- and.l d1,d2 ; mask off changed bits
- or.l d0,d2 ; or in set bits
- btst #$3,d4
- beq.s L0000CEC ; skip if not '040
-
- ; 0000 0101
- ror.l #1,d2 ; 8000 0080
- rol.w #8,d2 ; 8000 8000
- and.l #$80008000,d2 ;
-
- swap d3
- or.w d3,d2 ; keep '060 bits...
- swap d3
- swap d2 ; 8000 8000
-
- nop
- dc.w $F4F8 ; CPUSHA ic/dc ('040 only)
- ; update memory from caches
-
- L0000CEC:
- nop
- dc.w $4E7B,$2002 ; movec d2,cacr
- nop
-
- L0000CAE:
- move.l d3,d0 ; return old bits in d0
-
- movem.l (a7)+,d2-d4
- rts
-
- endif ; End of commented out lump
-
- ;*/endoverlay
- ; --------------------------------------------------------------
- ;*/endfile
-